package com.albert.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.*;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;

@Slf4j
public class HttpClientUtil {
    private static RequestConfig requestConfig = null;
    private static PoolingHttpClientConnectionManager cm = null;

    static {

        LayeredConnectionSocketFactory sslsf = null;
        try {
            sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
        } catch (NoSuchAlgorithmException e) {
            log.error("创建SSL连接失败");
        }
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("https", sslsf)
                .register("http", new PlainConnectionSocketFactory())
                .build();
        cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        //多线程调用注意配置，根据线程数设定
        cm.setMaxTotal(200);
        //多线程调用注意配置，根据线程数设定
        cm.setDefaultMaxPerRoute(300);
        requestConfig = RequestConfig.custom()
                //数据传输过程中数据包之间间隔的最大时间
                .setSocketTimeout(20000)
                //连接建立时间，三次握手完成时间
                .setConnectTimeout(20000)
                //重点参数
                .setExpectContinueEnabled(true)
                .setConnectionRequestTimeout(10000)
                .build();
    }
    public static String post(JSONObject headers, String url, JSONObject params) throws IOException {
        CloseableHttpClient httpClient = getHttpClient();
        CloseableHttpResponse closeableHttpResponse = null;
        // 创建post请求
        HttpPost httpPost = new HttpPost(url);
        if (headers != null) {
            Iterator iterator = headers.keySet().iterator();
            while (iterator.hasNext()) {
                String headerName = iterator.next().toString();
                httpPost.addHeader(headerName, headers.get(headerName).toString());
            }
        }
        httpPost.setConfig(requestConfig);
        httpPost.addHeader("Content-Type", "application/json");
        httpPost.addHeader("lastOperaTime", String.valueOf(System.currentTimeMillis()));
        if (params != null) {
            StringEntity stringEntity = new StringEntity(params.toJSONString(), "UTF-8");
            httpPost.setEntity(stringEntity);
        }
        closeableHttpResponse = httpClient.execute(httpPost);
        int statusCode = closeableHttpResponse.getStatusLine().getStatusCode();
        String response = null;
        if (statusCode == 200) {
            HttpEntity entity = closeableHttpResponse.getEntity();
            response = EntityUtils.toString(entity);
        }
        closeResponse(closeableHttpResponse);
        return response;
    }

    public static void closeResponse(CloseableHttpResponse closeableHttpResponse) throws IOException {
        EntityUtils.consume(closeableHttpResponse.getEntity());
        closeableHttpResponse.close();
    }

    /**
     * 忽略https证书验证
     *
     * @author lm
     * @version 1.0
     * @date 2023/07/03 09:42
     */
    public static CloseableHttpClient getHttpClient() {
        try {
            SSLContext sslc = SSLContext.getInstance("TLS");
            TrustManager[] trustManagerArray = {new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            }};
            sslc.init(null, trustManagerArray, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String s, SSLSession sslSession) {
                    return true;
                }
            });

            SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(sslc, NoopHostnameVerifier.INSTANCE);
            return HttpClients.custom()
                    .setSSLSocketFactory(ssf)
                    .build();

        } catch (Exception ex) {
            log.error("创建HttpClient链接异常->{}", ex.getMessage());
            return HttpClients.createDefault();
        }
    }
}
